package services

import (
	"crypto/md5"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"supershare/backend/models"
	"time"

	"github.com/beego/beego/v2/core/logs"
)

// DouyinAPIService 抖音API服务
type DouyinAPIService struct {
	BaseURL    string
	AppKey     string
	AppSecret  string
	HTTPClient *http.Client
}

// NewDouyinAPIService 创建抖音API服务实例
func NewDouyinAPIService() *DouyinAPIService {
	return &DouyinAPIService{
		BaseURL: "https://open.douyin.com",
		HTTPClient: &http.Client{
			Timeout: time.Second * 10,
		},
	}
}

// LoadConfig 加载抖音配置
func (s *DouyinAPIService) LoadConfig(storeId int64) error {
	// 获取抖音配置
	config, err := models.GetDouyinByStoreId(storeId)
	if err != nil {
		return fmt.Errorf("获取抖音配置失败: %v", err)
	}
	if config == nil {
		return fmt.Errorf("未找到抖音配置")
	}

	s.AppKey = config.AppKey
	s.AppSecret = config.AppSecret
	return nil
}

// generateSign 生成签名
func (s *DouyinAPIService) generateSign(params map[string]string) string {
	// 按键排序
	var keys []string
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	// 拼接参数
	var pairs []string
	for _, k := range keys {
		pairs = append(pairs, fmt.Sprintf("%s=%s", k, params[k]))
	}
	paramStr := strings.Join(pairs, "&")

	// 添加密钥
	signStr := paramStr + "&key=" + s.AppSecret

	// MD5加密
	hash := md5.Sum([]byte(signStr))
	return strings.ToUpper(fmt.Sprintf("%x", hash))
}

// UseVoucher 使用抖音券
func (s *DouyinAPIService) UseVoucher(orderId, voucherCode string) error {
	return s.retryUseVoucher(orderId, voucherCode, 3)
}

// retryUseVoucher 重试使用抖音券
func (s *DouyinAPIService) retryUseVoucher(orderId, voucherCode string, maxRetries int) error {
	var lastErr error
	for i := 0; i < maxRetries; i++ {
		err := s.doUseVoucher(orderId, voucherCode)
		if err == nil {
			return nil
		}
		lastErr = err
		logs.Warning("第%d次调用抖音API失败: %v", i+1, err)
		time.Sleep(time.Second * time.Duration(i+1)) // 递增重试间隔
	}
	return fmt.Errorf("重试%d次后仍然失败: %v", maxRetries, lastErr)
}

// doUseVoucher 执行使用抖音券
func (s *DouyinAPIService) doUseVoucher(orderId, voucherCode string) error {
	// 构建请求参数
	params := map[string]string{
		"order_id":     orderId,
		"voucher_code": voucherCode,
		"timestamp":    fmt.Sprintf("%d", time.Now().Unix()),
		"app_key":      s.AppKey,
	}

	// 生成签名
	params["sign"] = s.generateSign(params)

	// 构建请求URL
	url := fmt.Sprintf("%s/api/v1/voucher/use", s.BaseURL)

	// 将参数转换为url.Values
	values := make(map[string][]string)
	for k, v := range params {
		values[k] = []string{v}
	}

	// 发送POST请求
	resp, err := s.HTTPClient.PostForm(url, values)
	if err != nil {
		return fmt.Errorf("调用抖音API失败: %v", err)
	}
	defer resp.Body.Close()

	// 解析响应
	var result struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return fmt.Errorf("解析抖音API响应失败: %v", err)
	}

	if result.Code != 0 {
		return fmt.Errorf("抖音API返回错误: %s", result.Msg)
	}

	return nil
}

// SyncGroups 同步抖音团购活动
func (s *DouyinAPIService) SyncGroups(poiId string) ([]map[string]interface{}, error) {
	// 构建请求参数
	params := map[string]string{
		"poi_id":    poiId,
		"timestamp": fmt.Sprintf("%d", time.Now().Unix()),
		"app_key":   s.AppKey,
	}

	// 生成签名
	params["sign"] = s.generateSign(params)

	// 构建请求URL
	apiURL := fmt.Sprintf("%s/api/v1/group/list", s.BaseURL)

	// 将参数转换为url.Values
	values := make(map[string][]string)
	for k, v := range params {
		values[k] = []string{v}
	}

	// 发送GET请求
	resp, err := s.HTTPClient.Get(apiURL + "?" + url.Values(values).Encode())
	if err != nil {
		return nil, fmt.Errorf("调用抖音API失败: %v", err)
	}
	defer resp.Body.Close()

	// 解析响应
	var result struct {
		Code int                      `json:"code"`
		Msg  string                   `json:"msg"`
		Data []map[string]interface{} `json:"data"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, fmt.Errorf("解析抖音API响应失败: %v", err)
	}

	if result.Code != 0 {
		return nil, fmt.Errorf("抖音API返回错误: %s", result.Msg)
	}

	return result.Data, nil
}

// SyncOrders 同步抖音订单
func (s *DouyinAPIService) SyncOrders(poiId string, startTime, endTime int64) ([]map[string]interface{}, error) {
	// 构建请求参数
	params := map[string]string{
		"poi_id":     poiId,
		"start_time": fmt.Sprintf("%d", startTime),
		"end_time":   fmt.Sprintf("%d", endTime),
		"timestamp":  fmt.Sprintf("%d", time.Now().Unix()),
		"app_key":    s.AppKey,
	}

	// 生成签名
	params["sign"] = s.generateSign(params)

	// 构建请求URL
	apiURL := fmt.Sprintf("%s/api/v1/order/list", s.BaseURL)

	// 将参数转换为url.Values
	values := make(map[string][]string)
	for k, v := range params {
		values[k] = []string{v}
	}

	// 发送GET请求
	resp, err := s.HTTPClient.Get(apiURL + "?" + url.Values(values).Encode())
	if err != nil {
		return nil, fmt.Errorf("调用抖音API失败: %v", err)
	}
	defer resp.Body.Close()

	// 解析响应
	var result struct {
		Code int                      `json:"code"`
		Msg  string                   `json:"msg"`
		Data []map[string]interface{} `json:"data"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, fmt.Errorf("解析抖音API响应失败: %v", err)
	}

	if result.Code != 0 {
		return nil, fmt.Errorf("抖音API返回错误: %s", result.Msg)
	}

	return result.Data, nil
}

// GetGroupDetail 获取团购活动详情
func (s *DouyinAPIService) GetGroupDetail(groupId string) (map[string]interface{}, error) {
	params := map[string]string{
		"group_id":  groupId,
		"timestamp": fmt.Sprintf("%d", time.Now().Unix()),
		"app_key":   s.AppKey,
	}

	params["sign"] = s.generateSign(params)
	apiURL := fmt.Sprintf("%s/api/v1/group/detail", s.BaseURL)

	values := make(map[string][]string)
	for k, v := range params {
		values[k] = []string{v}
	}

	resp, err := s.HTTPClient.Get(apiURL + "?" + url.Values(values).Encode())
	if err != nil {
		return nil, fmt.Errorf("调用抖音API失败: %v", err)
	}
	defer resp.Body.Close()

	var result struct {
		Code int                    `json:"code"`
		Msg  string                 `json:"msg"`
		Data map[string]interface{} `json:"data"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, fmt.Errorf("解析抖音API响应失败: %v", err)
	}

	if result.Code != 0 {
		return nil, fmt.Errorf("抖音API返回错误: %s", result.Msg)
	}

	return result.Data, nil
}

// GetOrderDetail 获取订单详情
func (s *DouyinAPIService) GetOrderDetail(orderId string) (map[string]interface{}, error) {
	params := map[string]string{
		"order_id":  orderId,
		"timestamp": fmt.Sprintf("%d", time.Now().Unix()),
		"app_key":   s.AppKey,
	}

	params["sign"] = s.generateSign(params)
	apiURL := fmt.Sprintf("%s/api/v1/order/detail", s.BaseURL)

	values := make(map[string][]string)
	for k, v := range params {
		values[k] = []string{v}
	}

	resp, err := s.HTTPClient.Get(apiURL + "?" + url.Values(values).Encode())
	if err != nil {
		return nil, fmt.Errorf("调用抖音API失败: %v", err)
	}
	defer resp.Body.Close()

	var result struct {
		Code int                    `json:"code"`
		Msg  string                 `json:"msg"`
		Data map[string]interface{} `json:"data"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, fmt.Errorf("解析抖音API响应失败: %v", err)
	}

	if result.Code != 0 {
		return nil, fmt.Errorf("抖音API返回错误: %s", result.Msg)
	}

	return result.Data, nil
}

// RefundOrder 退款订单
func (s *DouyinAPIService) RefundOrder(orderId string, refundAmount int) error {
	params := map[string]string{
		"order_id":     orderId,
		"refund_amount": fmt.Sprintf("%d", refundAmount),
		"timestamp":    fmt.Sprintf("%d", time.Now().Unix()),
		"app_key":      s.AppKey,
	}

	params["sign"] = s.generateSign(params)
	apiURL := fmt.Sprintf("%s/api/v1/order/refund", s.BaseURL)

	values := make(map[string][]string)
	for k, v := range params {
		values[k] = []string{v}
	}

	resp, err := s.HTTPClient.PostForm(apiURL, values)
	if err != nil {
		return fmt.Errorf("调用抖音API失败: %v", err)
	}
	defer resp.Body.Close()

	var result struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return fmt.Errorf("解析抖音API响应失败: %v", err)
	}

	if result.Code != 0 {
		return fmt.Errorf("抖音API返回错误: %s", result.Msg)
	}

	return nil
}
